home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / StaffCalibration.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  9.3 KB  |  382 lines  |  [TEXT/KAHL]

  1. /* StaffCalibration.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "StaffCalibration.h"
  31. #include "Frequency.h"
  32. #include "NoteObject.h"
  33. #include "Memory.h"
  34.  
  35.  
  36. /* a note line every 4 scan lines (a note line is 1/2 of a staff line, or */
  37. /* a line on which a note may be plotted) */
  38. #define STAFFSEPARATION (4)
  39.  
  40. /* total number of pixels that are in the drawing range */
  41. #define TOTALPIXELS ((NUMNOTES / 12) * 7 * STAFFSEPARATION)
  42.  
  43.  
  44. /* get the maximum number of vertical pixels needed to represent score range */
  45. OrdType                        MaxVerticalSize(void)
  46.     {
  47.         return TOTALPIXELS;
  48.     }
  49.  
  50.  
  51. /* get the pixel offset of the center note */
  52. OrdType                        GetCenterNotePixel(void)
  53.     {
  54.         return (TOTALPIXELS - 1) - ((CENTERNOTE / 12) * (7 * STAFFSEPARATION));
  55.     }
  56.  
  57.  
  58. /* convert pitch to vertical pixel offset. */
  59. OrdType                        ConvertPitchToPixel(short HalfStep, unsigned short SharpFlatFlags)
  60.     {
  61.         int                            Octave;
  62.         OrdType                    NoteOffset;
  63.  
  64.         ERROR((SharpFlatFlags & ~(eFlatModifier | eSharpModifier)) != 0,PRERR(ForceAbort,
  65.             "ConvertPitchToPixel:  extraneous bits in SharpFlatFlags"));
  66.         ERROR((HalfStep < 0) || (HalfStep >= NUMNOTES - 1),PRERR(ForceAbort,
  67.             "ConvertPitchToPixel:  pitch index is out of range"));
  68.         Octave = HalfStep / 12;
  69.         switch (HalfStep % 12)
  70.             {
  71.                 case 0: /* B#/C */
  72.                     if ((SharpFlatFlags & eSharpModifier) != 0)
  73.                         {
  74.                             NoteOffset = -1 * STAFFSEPARATION;
  75.                         }
  76.                     else
  77.                         {
  78.                             NoteOffset = 0 * STAFFSEPARATION;
  79.                         }
  80.                     break;
  81.                 case 1: /* C#/Db */
  82.                     if ((SharpFlatFlags & eSharpModifier) != 0)
  83.                         {
  84.                             NoteOffset = 0 * STAFFSEPARATION;
  85.                         }
  86.                      else
  87.                         {
  88.                             NoteOffset = 1 * STAFFSEPARATION;
  89.                         }
  90.                     break;
  91.                 case 2: /* D */
  92.                     NoteOffset = 1 * STAFFSEPARATION;
  93.                     break;
  94.                 case 3: /* D#/Eb */
  95.                     if ((SharpFlatFlags & eSharpModifier) != 0)
  96.                         {
  97.                             NoteOffset = 1 * STAFFSEPARATION;
  98.                         }
  99.                      else
  100.                         {
  101.                             NoteOffset = 2 * STAFFSEPARATION;
  102.                         }
  103.                     break;
  104.                 case 4: /* E/Fb */
  105.                     if ((SharpFlatFlags & eFlatModifier) != 0)
  106.                         {
  107.                             NoteOffset = 3 * STAFFSEPARATION;
  108.                         }
  109.                      else
  110.                         {
  111.                             NoteOffset = 2 * STAFFSEPARATION;
  112.                         }
  113.                     break;
  114.                 case 5: /* E#/F */
  115.                     if ((SharpFlatFlags & eSharpModifier) != 0)
  116.                         {
  117.                             NoteOffset = 2 * STAFFSEPARATION;
  118.                         }
  119.                      else
  120.                         {
  121.                             NoteOffset = 3 * STAFFSEPARATION;
  122.                         }
  123.                     break;
  124.                 case 6: /* F#/Gb */
  125.                     if ((SharpFlatFlags & eSharpModifier) != 0)
  126.                         {
  127.                             NoteOffset = 3 * STAFFSEPARATION;
  128.                         }
  129.                      else
  130.                         {
  131.                             NoteOffset = 4 * STAFFSEPARATION;
  132.                         }
  133.                     break;
  134.                 case 7: /* G */
  135.                     NoteOffset = 4 * STAFFSEPARATION;
  136.                     break;
  137.                 case 8: /* G#/Ab */
  138.                     if ((SharpFlatFlags & eSharpModifier) != 0)
  139.                         {
  140.                             NoteOffset = 4 * STAFFSEPARATION;
  141.                         }
  142.                      else
  143.                         {
  144.                             NoteOffset = 5 * STAFFSEPARATION;
  145.                         }
  146.                     break;
  147.                 case 9: /* A */
  148.                     NoteOffset = 5 * STAFFSEPARATION;
  149.                     break;
  150.                 case 10: /* A#/Bb */
  151.                     if ((SharpFlatFlags & eSharpModifier) != 0)
  152.                         {
  153.                             NoteOffset = 5 * STAFFSEPARATION;
  154.                         }
  155.                      else
  156.                         {
  157.                             NoteOffset = 6 * STAFFSEPARATION;
  158.                         }
  159.                     break;
  160.                 case 11: /* B/Cb */
  161.                     if ((SharpFlatFlags & eFlatModifier) != 0)
  162.                         {
  163.                             NoteOffset = 7 * STAFFSEPARATION;
  164.                         }
  165.                      else
  166.                         {
  167.                             NoteOffset = 6 * STAFFSEPARATION;
  168.                         }
  169.                     break;
  170.             }
  171.         NoteOffset += 7 * STAFFSEPARATION * Octave;
  172.         return (TOTALPIXELS - 1) - NoteOffset;
  173.     }
  174.  
  175.  
  176. static OrdType        OneOctaveHalfStepTable[] =
  177.     {
  178.         0, /* pixel 0 == C */
  179.         2, /* pixel 4 == D */
  180.         4, /* pixel 8 == E */
  181.         5, /* pixel 12 == F */
  182.         7, /* pixel 16 == G */
  183.         9, /* pixel 20 == A */
  184.         11 /* pixel 24 == B */
  185.     };
  186. #define OneOctaveHalfStepSize (sizeof(OneOctaveHalfStepTable)\
  187.                     / sizeof(OneOctaveHalfStepTable[0]))
  188.  
  189.  
  190. /* convert pixel offset to halfstep value */
  191. short                            ConvertPixelToPitch(OrdType Pixel)
  192.     {
  193.         short                        OctaveCount;
  194.         short                        ReturnValue;
  195.  
  196.         Pixel = ((TOTALPIXELS - 1) - Pixel + 1) / STAFFSEPARATION;
  197.         if (Pixel < 0)
  198.             {
  199.                 Pixel = 0;
  200.             }
  201.         OctaveCount = 0;
  202.         while (Pixel >= OneOctaveHalfStepSize)
  203.             {
  204.                 Pixel -= OneOctaveHalfStepSize;
  205.                 OctaveCount += 1;
  206.             }
  207.         ReturnValue = OctaveCount * 12 + OneOctaveHalfStepTable[Pixel];
  208.         if (ReturnValue > NUMNOTES - 1)
  209.             {
  210.                 ReturnValue = NUMNOTES - 1;
  211.             }
  212.         return ReturnValue;
  213.     }
  214.  
  215.  
  216. #define MajorStaffSize (10)
  217. static short            MajorStaffList[MajorStaffSize] =
  218.     {
  219.         CENTERNOTE + 4, /* E */
  220.         CENTERNOTE + 7, /* G */
  221.         CENTERNOTE + 11, /* B */
  222.         CENTERNOTE + 14, /* D */
  223.         CENTERNOTE + 17, /* F */
  224.         CENTERNOTE - 4, /* A */
  225.         CENTERNOTE - 7, /* F */
  226.         CENTERNOTE - 11, /* D */
  227.         CENTERNOTE - 14, /* B */
  228.         CENTERNOTE - 17 /* G */
  229.     };
  230.  
  231.  
  232. /* get statically allocated list of major staff lines (10 elements in list) */
  233. short*                        GetMajorStaffList(void)
  234.     {
  235.         return MajorStaffList;
  236.     }
  237.  
  238.  
  239. /* get length of staff list */
  240. long                            GetMajorStaffListLength(void)
  241.     {
  242.         return MajorStaffSize;
  243.     }
  244.  
  245.  
  246. #define TwoOctaveStaffSize (7)
  247. static OrdType        TwoOctaveStaffTable[TwoOctaveStaffSize] =
  248.     {
  249.         0, /* C0 */
  250.         4, /* E0 */
  251.         7, /* G0 */
  252.         11, /* B0 */
  253.         14, /* D1 */
  254.         17, /* F1 */
  255.         21 /* A1 */
  256.     };
  257.  
  258.  
  259. /* append the value to the array.  if it fails, then the array is disposed */
  260. /* and NIL is returned */
  261. static short*            AppendArray(short* Array, short Value)
  262.     {
  263.         short*                        NewArray;
  264.         long                            Size;
  265.  
  266.         Size = PtrSize((char*)Array);
  267.         NewArray = (short*)ResizePtr((char*)Array,Size + sizeof(short));
  268.         if (NewArray == NIL)
  269.             {
  270.                 ReleasePtr((char*)Array);
  271.                 return NIL;
  272.             }
  273.         NewArray[Size / sizeof(short)] = Value;
  274.         return NewArray;
  275.     }
  276.  
  277.  
  278. /* get dynamically allocated list of minor staff lines */
  279. short*                        GetMinorStaffList(void)
  280.     {
  281.         short                            HalfStep;
  282.         short*                        Table;
  283.  
  284.         Table = (short*)AllocPtrCanFail(0,"GetMinorStaffList");
  285.         if (Table == NIL)
  286.             {
  287.                 return NIL;
  288.             }
  289.         for (HalfStep = 0; HalfStep < NUMNOTES; HalfStep += 1)
  290.             {
  291.  
  292.                 if ((HalfStep < CENTERNOTE - 17) || (HalfStep > CENTERNOTE + 17))
  293.                     {
  294.                         short                            TwoOctRelative;
  295.                         int                                Scan;
  296.  
  297.                         TwoOctRelative = HalfStep - CENTERNOTE;
  298.                         while (TwoOctRelative < 0)
  299.                             {
  300.                                 TwoOctRelative += 24;
  301.                             }
  302.                         while (TwoOctRelative >= 24)
  303.                             {
  304.                                 TwoOctRelative -= 24;
  305.                             }
  306.                         for (Scan = 0; Scan < TwoOctaveStaffSize; Scan += 1)
  307.                             {
  308.                                 if (TwoOctRelative == TwoOctaveStaffTable[Scan])
  309.                                     {
  310.                                         Table = AppendArray(Table,HalfStep);
  311.                                         if (Table == NIL)
  312.                                             {
  313.                                                 return NIL;
  314.                                             }
  315.                                     }
  316.                             }
  317.                     }
  318.             }
  319.         return Table;
  320.     }
  321.  
  322.  
  323. /* set up note */
  324. void                            SetUpNoteInfo(short* Pitch, unsigned long* SharpFlatThing,
  325.                                         MyBoolean Sharp, MyBoolean Flat, OrdType Pixel)
  326.     {
  327.         ERROR((Pitch == NIL) || (SharpFlatThing == NIL),PRERR(ForceAbort,
  328.             "SetUpNoteInfo:  output parameter is NIL"));
  329.         *SharpFlatThing = 0;
  330.         *Pitch = ConvertPixelToPitch(Pixel);
  331.         if (Sharp)
  332.             {
  333.                 switch (*Pitch % 12)
  334.                     {
  335.                         case 0: /* C */
  336.                         case 2: /* D */
  337.                         case 5: /* F */
  338.                         case 7: /* G */
  339.                         case 9: /* A */
  340.                             *Pitch += 1;
  341.                             *SharpFlatThing |= eSharpModifier;
  342.                             break;
  343.                         case 4: /* E */
  344.                         case 11: /* B */
  345.                             *Pitch += 1;
  346.                             break;
  347.                         default:
  348.                             /* ? */
  349.                             break;
  350.                     }
  351.             }
  352.         if (Flat)
  353.             {
  354.                 switch (*Pitch % 12)
  355.                     {
  356.                         case 2: /* D */
  357.                         case 4: /* E */
  358.                         case 7: /* G */
  359.                         case 9: /* A */
  360.                         case 11: /* B */
  361.                             *Pitch -= 1;
  362.                             *SharpFlatThing |= eFlatModifier;
  363.                             break;
  364.                         case 0: /* C */
  365.                         case 5: /* F */
  366.                             *Pitch -= 1;
  367.                             break;
  368.                         default:
  369.                             /* ? */
  370.                             break;
  371.                     }
  372.             }
  373.         if (*Pitch < 0)
  374.             {
  375.                 *Pitch = 0;
  376.             }
  377.         if (*Pitch > NUMNOTES - 1)
  378.             {
  379.                 *Pitch = NUMNOTES - 1;
  380.             }
  381.     }
  382.